package org.example.sys.security;

import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;

import java.security.Key;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Date;
import java.util.Map;

/**
 * JWT 工具类
 */
public class JwtUtils {
    // 使用 HMAC-SHA256 算法生成密钥
    private static final Key HMAC_KEY = Keys.secretKeyFor(SignatureAlgorithm.HS256);

    // 使用 RSA 算法生成密钥对
    private static final KeyPair RSA_KEY_PAIR = Keys.keyPairFor(SignatureAlgorithm.RS256);
    private static final PrivateKey RSA_PRIVATE_KEY = RSA_KEY_PAIR.getPrivate();
    private static final PublicKey RSA_PUBLIC_KEY = RSA_KEY_PAIR.getPublic();

    // 默认过期时间（单位：毫秒）
    private static final long DEFAULT_EXPIRATION = 3600000L; // 1小时

    /**
     * 生成使用 HMAC 加密的 JWT Token
     *
     * @param claims     自定义声明
     * @param expiration 过期时间（毫秒）
     * @return JWT Token
     */
    public static String generateHmacToken(Map<String, Object> claims, long expiration) {
        return Jwts.builder()
                .setClaims(claims) // 自定义声明
                .setIssuedAt(new Date()) // 签发时间
                .setExpiration(new Date(System.currentTimeMillis() + expiration)) // 过期时间
                .signWith(HMAC_KEY) // 使用 HMAC 密钥签名
                .compact();
    }

    /**
     * 生成使用 RSA 加密的 JWT Token
     *
     * @param claims     自定义声明
     * @param expiration 过期时间（毫秒）
     * @return JWT Token
     */
    public static String generateRsaToken(Map<String, Object> claims, long expiration) {
        return Jwts.builder()
                .setClaims(claims) // 自定义声明
                .setIssuedAt(new Date()) // 签发时间
                .setExpiration(new Date(System.currentTimeMillis() + expiration)) // 过期时间
                .signWith(RSA_PRIVATE_KEY, SignatureAlgorithm.RS256) // 使用 RSA 私钥签名
                .compact();
    }

    /**
     * 解析使用 HMAC 加密的 JWT Token
     *
     * @param token JWT Token
     * @return 解析后的 Claims
     * @throws JwtException 如果解析失败或 Token 无效
     */
    public static Claims parseHmacToken(String token) throws JwtException {
        JwtParser parser = Jwts.parserBuilder()
                .setSigningKey(HMAC_KEY) // 设置 HMAC 密钥
                .build();
        return parser.parseClaimsJws(token).getBody();
    }

    /**
     * 解析使用 RSA 加密的 JWT Token
     *
     * @param token JWT Token
     * @return 解析后的 Claims
     * @throws JwtException 如果解析失败或 Token 无效
     */
    public static Claims parseRsaToken(String token) throws JwtException {
        JwtParser parser = Jwts.parserBuilder()
                .setSigningKey(RSA_PUBLIC_KEY) // 设置 RSA 公钥
                .build();
        return parser.parseClaimsJws(token).getBody();
    }

    /**
     * 验证 JWT Token 是否有效
     *
     * @param token    JWT Token
     * @param isHmac   是否使用 HMAC 算法
     * @return 是否有效
     */
    public static boolean validateToken(String token, boolean isHmac) {
        try {
            if (isHmac) {
                parseHmacToken(token); // 如果解析成功，则 Token 有效
            } else {
                parseRsaToken(token);
            }
            return true;
        } catch (JwtException e) {
            return false; // 解析失败，Token 无效
        }
    }
}